<template>
  <div class="view-container">
    <div class="header_info">
      <div class="header_info_t">
        <div class="header_info_t_l">
          <el-button type="primary">选择数据</el-button>
        </div>
        <div class="header_info_t_m1">
          <div class="header_info_t_m1_tit" :title="rawInfo.title">
            路测数据名称：{{ rawInfo.title }}
          </div>
          <div class="header_info_t_m1_time">
            <el-date-picker
              v-model="timeRange"
              type="datetimerange"
              range-separator="至"
              start-placeholder="开始时间"
              end-placeholder="结束时间"
              @change="changeDatePicker"
            />
          </div>
        </div>
        <div class="header_info_t_m2">
          <el-slider
            v-model="sliderValue"
            range
            :min="0"
            :max="timeMaxSpanSecond"
            :step="1"
            show-tooltip
            :format-tooltip="formatTooltip"
            :marks="marks"
            @change="changeSlider"
          />
        </div>
        <div class="header_info_t_r">
          规则：<br />
          1、小于1分钟，数据颗粒度：点位/20ms<br />
          2、1分钟到10分钟，数据颗粒度：点位/200ms<br />
          3、10分钟以上，数据颗粒度：点位/2s<br />
        </div>
      </div>

      <div class="header_info_b">
        <ul>
          <li
            :class="{ active: activeName == 'execute' }"
            @click="switchTab('execute')"
          >
            执行分析
          </li>
          <li
            :class="{ active: activeName == 'control' }"
            @click="switchTab('control')"
          >
            误差分析
          </li>
        </ul>
      </div>
    </div>

    <div class="main_content" ref="main_content" v-loading="loading">
      <div class="tabConent" v-show="activeName == 'execute'">
        <!-- 右侧导航 -->
        <pi-fixed-tabs :data="tabs.execute" :parentDom="$refs['execute']" current="controlGearDataMap"></pi-fixed-tabs>
        <!-- 执行分析 start -->
        <div class="tabConentItems" ref="execute">
          <item-view
            :ref="key"
            v-for="(value, key) in echartData.groups.execute"
            :data="value.data"
            :key="key"
          ></item-view>
        </div>
        <!-- 执行分析 end -->
      </div>
      <div class="tabConent" v-show="activeName == 'control'">
        <!-- 右侧导航 -->
        <pi-fixed-tabs :data="tabs.control" :parentDom="$refs['control']" current="controlLateralDataMap"></pi-fixed-tabs>
        <!-- 控制分析 start -->
        <div class="tabConentItems" ref="control">
          <item-view
            :ref="key"
            v-for="(value, key) in echartData.groups.control"
            :data="value.data"
            :key="key"
          ></item-view>
        </div>
        <!-- 控制分析 end -->
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import ItemView from "./item-view.vue";
import { getCarcontrolData } from "@/api/takeoverAnalysis/takeoverAnalysis";
import { defineComponent } from "vue";
import { ElMessage } from "element-plus";
import { formatDate, resHandle } from "@/utils/utils";
import { default as Item, hashItem } from "./ItemClass";
// import * as echarts from "echarts";
import piFixedTabs from "./pi-fixed-tabs.vue";
export default defineComponent({
  components: { ItemView, piFixedTabs },
  data() {
    return {
      loading: true,
      rawInfo: {
        title: "",
        rawId: "",
        beginDataTime: new Date(),
        endDataTime: new Date(),
      } as any,
      activeName: "execute",
      //曲线图数据配置
      echartData: {
        dates: [] as string[],
        groups: {
          //执行分析
          execute: {
            controlGearDataMap: {
              ref: null as any,
              data: new Item("档位", "cGear", ["real", "target"]),
            },
            executeSteerDataMap: {
              ref: null as any,
              data: new Item("转角执行误差", "eSteer", [
                "error",
                "real",
                "target",
                "maximum",
                "minimum",
                "average",
                "variance",
              ]),
            },
            controlSpeedDataMap: {
              ref: null as any,
              data: new Item("速度控制误差", "cSpeed", [
                "error",
                "real",
                "target",
                "maximum",
                "minimum",
                "average",
                "variance",
              ]),
            },
            controlAccelerationDataMap: {
              ref: null as any,
              data: new Item("加速度控制误差", "cAcceleration", [
                "error",
                "real",
                "target",
                "maximum",
                "minimum",
                "average",
                "variance",
              ]),
            },
          },
          //控制分析
          control: {
            controlLateralDataMap: {
              ref: null as any,
              data: new Item("横向控制误差", "cLateral", [
                "error",
                "maximum",
                "minimum",
                "average",
                "variance",
              ]),
            },
            controlHeadingDataMap: {
              ref: null as any,
              data: new Item("航向角控制误差", "cHeading", [
                "error",
                "maximum",
                "minimum",
                "average",
                "variance",
              ]),
            },
            controlStationDataMap: {
              ref: null as any,
              data: new Item("纵向位置控制误差", "cStation", [
                "error",
                "maximum",
                "minimum",
                "average",
                "variance",
              ]),
            },
          },
        },
        isFresh: {
          execute: false,
          control: false,
        },
      },
      span: 20, //数据粒度 2000,200,20
      sliderValue: [1, 1],
      timeRange: [new Date(), new Date()],
      tabs: {} as any,
    };
  },
  computed: {
    //slider打标记
    marks() {
      // 默认标记起止位置
      let marks = {
        0: formatDate(this.rawInfo.beginDataTime, "yyyy-MM-dd HH:mm:ss"),
        [this.timeMaxSpanSecond]: formatDate(
          this.rawInfo.endDataTime,
          "yyyy-MM-dd HH:mm:ss"
        ),
      };
      let mid=Math.floor(this.timeMaxSpanSecond/2);
      let midTime=new Date(this.rawInfo.beginDataTime);
      midTime.setSeconds(midTime.getSeconds()+mid);
      marks[mid]=formatDate(midTime, "yyyy-MM-dd HH:mm:ss");
      return marks;
    },
    //本次路测起止时间间隔：ms
    timeMaxSpan() {
      let sp =
        this.rawInfo.endDataTime.getTime() -
        this.rawInfo.beginDataTime.getTime();
      return sp;
    },
    //本次路测起止时间间隔：s
    timeMaxSpanSecond() {
      let sp =
        this.rawInfo.endDataTime.getTime() -
        this.rawInfo.beginDataTime.getTime();
      return Math.ceil(sp / 1000);
    },
  },
  async created() {},
  async mounted() {
    let that = this;
    //拉取最新一条路测数据
    let resLatest = await this.getLatestRawInfo();

    //获取echart宽度
    let echartWidth = "";
    if (this.activeName == "control") {
      echartWidth = this.$refs["control"].offsetWidth - 30;
    } else {
      echartWidth = this.$refs["execute"].offsetWidth - 30;
    }
    // 初始化tab
    this.getTabs();

    // ehcart设置组合
    groupConnect("execute");
    groupConnect("control");

    // 生成时间轴
    this.getDates(this.span); //需要传入span,默认2000ms

    // 拉取对应车控数据
    let res = await this.getData();

    // 数据处理
    this.handleData(res);

    // 渲染
    this.buildEchart();
    function groupConnect(groupName: string) {
      let group = Object.keys(that.echartData.groups[groupName]).map((item) => {
        let ins = that.$refs[item][0].init(echartWidth + "px");
        ins.group = groupName;
        return ins;
      });
      that.$echarts.connect(group);
    }
  },
  methods: {
    // tabs导航菜单
    getTabs() {
      let tabs: any = {};
      let groups = this.echartData.groups;
      Object.keys(groups).forEach((key: any) => {
        tabs[key] = Object.keys(groups[key]).map((key2: any) => {
          return {
            label: groups[key][key2].data.title,
            value: key2,
            ref: this.$refs[key2][0].$el,
          };
        });
      });
      this.tabs = tabs;
    },
    // datepicker改完,slider同步滑动
    changeDatePicker(value) {
      let start = countSpSecond(this.rawInfo.beginDataTime, value[0]);
      let end = countSpSecond(this.rawInfo.beginDataTime, value[1]);
      this.sliderValue = [start, end];
      function countSpSecond(roottime, curtime) {
        let sp = new Date(curtime).getTime() - new Date(roottime).getTime();
        return Math.floor(sp / 1000);
      }
    },
    // slider滑动,datepicker同步改
    changeSlider(val: Array<Number> = [0, 0]) {
      let start = new Date(this.rawInfo.beginDataTime);
      let end = new Date(this.rawInfo.beginDataTime);
      start.setSeconds(start.getSeconds() + val[0]);
      end.setSeconds(end.getSeconds() + val[1]);
      this.timeRange = [start, end];
    },
    async getLatestRawInfo() {
      // 拉数据
      // ...
      this.rawInfo = {
        title: "123_NAP_2022123212_的接口萨拉大大",
        rawId: "1520000000009",
        timeId: 2,
        beginDataTime: new Date("2022-05-01 14:37:31.000"),
        endDataTime: new Date("2022-05-01 14:37:40.000"),
      };

      // 重置timepicker中时间
      this.timeRange = [this.rawInfo.beginDataTime, this.rawInfo.endDataTime];

      return this.rawInfo;
    },
    //渲染折线图
    buildEchart() {
      // debugger;
      if (this.echartData.isFresh[this.activeName]) {
        return;
      }
      this.echartData.isFresh[this.activeName] = true;

      Object.keys(this.echartData.groups[this.activeName]).forEach(
        (itemKey: any) => {
          this.$refs[itemKey][0].render();
        }
      );
    },
    // 切换tab
    switchTab(activeName: any) {
      this.activeName = activeName;
      this.buildEchart();
    },
    // 数据处理
    handleData(res: any) {
      let that = this;
      if (res.code != 0) {
        return;
      }
      let data = res.data;
      handleData("execute");
      handleData("control");
      function handleData(groupName: any) {
        let groupData = that.echartData.groups[groupName] as any;
        Object.keys(groupData).forEach((itemKey: any) => {
          let item: Item = groupData[itemKey].data;
          item.dates = that.echartData.dates;
          //重置
          item.reset();
          let D = data[itemKey];
          if (item.showFields.includes("error")) {
            setDate("");
          }
          if (item.showFields.includes("real")) {
            setDate("Real");
          }
          if (item.showFields.includes("target")) {
            setDate("Target");
          }

          item.setHashList(that.timeRange[0], that.timeRange[1], that.span);

          //给item.rawData赋值
          function setDate(name: string = "") {
            if (
              typeof D[`${item.valueField}${name}`] != "undefined" &&
              typeof D[`${item.valueField}${name}`]["list"] != "undefined"
            ) {
              item.rawData[name || "list"] =
                D[`${item.valueField}${name}`]["list"];
            }
          }
        });
      }
    },
    // 拉数据
    async getData() {
      // 重置tab加载标记
      this.echartData.isFresh.execute = false;
      this.echartData.isFresh.control = false;

      // 判断采用哪种抽稀数据
      let timeId = 0;
      if (this.timeMaxSpan < 60000) {
        // 一分钟内
        timeId = 0;
      } else if (this.timeMaxSpan < 600000) {
        // 1分钟到10分钟
        timeId = 1;
      } else {
        // 10分钟以上
        timeId = 2;
      }
      this.sliderValue[1] = this.timeMaxSpanSecond;

      this.loading = true;
      let param = {
        rawId: this.rawInfo.rawId,
        timeId: timeId,
        beginDataTime: this.rawInfo.beginDataTime,
        endDataTime: this.rawInfo.endDataTime,
      };
      console.log(param);
      let res = await getCarcontrolData(param);
      this.loading = false;
      return res;
    },
    //slider 提示回调
    formatTooltip(value: any) {
      let start = new Date(this.rawInfo.beginDataTime);
      start.setSeconds(start.getSeconds() + value);
      return start.format("yyyy-MM-dd hh:mm:ss");
    },
    // 生成时间轴
    getDates(span = 2000) {
      let start: any = this.timeRange[0]
        .getTime()
        .toString()
        .replace(/\d{3}$/, "000");
      let end: any = this.timeRange[1]
        .getTime()
        .toString()
        .replace(/\d{3}$/, "000");
      start = parseInt(start);
      end = parseInt(end);
      let dates: any[] = [];
      while (start <= end) {
        dates.push(
          formatDate(new Date(start), "yyyy-MM-dd HH:mm:ss") +
            `.` +
            start.toString().slice(-3)
        );
        start += span;
      }
      this.echartData.dates = dates;
    },
  },
});
Date.prototype.format = function (fmt) {
  var o = {
    "M+": this.getMonth() + 1, //月份
    "d+": this.getDate(), //日
    "h+": this.getHours(), //小时
    "m+": this.getMinutes(), //分
    "s+": this.getSeconds(), //秒
    "q+": Math.floor((this.getMonth() + 3) / 3), //季度
    S: this.getMilliseconds(), //毫秒
  };
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(
      RegExp.$1,
      (this.getFullYear() + "").substr(4 - RegExp.$1.length)
    );
  }
  for (var k in o) {
    if (new RegExp("(" + k + ")").test(fmt)) {
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)
      );
    }
  }
  return fmt;
};
</script>
<style lang="scss">
//
</style>
<style  lang="scss" scoped>
.view-container {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;

  .header_info {
    display: flex;
    flex-direction: column;
    height: 160px;
    background-color: white;
    border-radius: 4px;
    font-size: 12px;
    text-align: left;
    margin-top: 30px;
    .header_info_t {
      display: flex;
      flex-direction: row;
      justify-content: space-between;
      height: 70px;
      padding: 15px 0;
      border-bottom: 1px solid #ddd;
      .header_info_t_l {
        border-right: 1px solid #ddd;
        padding: 0 20px;
        display: flex;
        flex-direction: column;
        justify-content: center;
      }
      .header_info_t_m1 {
        width: 400px;
        padding: 0 15px;
        display: flex;
        flex-direction: column;
        .header_info_t_m1_tit {
          flex: 1;
          font-size: 18px;
          color: #333;
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
        }
        .header_info_t_m1_time {
          height: 32px;
        }
      }
      .header_info_t_m2 {
        flex: 1;
        padding: 0 40px;
        :deep(.el-slider__marks-text){
          text-align: center;
          white-space: normal;
          display:inline-block;
          width:80px;
        }
      }
      .header_info_t_r {
        border-left: 1px solid #ddd;
        padding: 0 10px;
        color: #555;
      }
    }
    .header_info_b {
      display: flex;
      flex-direction: column;
      justify-content: center;
      flex: 1;
      & > ul {
        list-style: none;
        margin: 0;
        padding: 0;
        & > li {
          float: left;
          height: 36px;
          padding: 0 0px;
          color: #999;
          line-height: 36px;
          font-size: 16px;
          margin: 0 10px;
          cursor: pointer;
        }
        & > li.active {
          color: #1c3dd7;
          border-bottom: 2px solid #1c3dd7;
        }
      }
    }
  }

  .main_content {
    background-color: white;
    border-radius: 4px;
    margin-top: 10px;
    padding: 10px;
    flex-grow: 1;
    flex-shrink: 1;
    display: flex;
    flex-direction: column;
    .tabConent {
      position: relative;
      flex: 1;
      display: flex;
      flex-direction: column;
      .tabConentItems {
        position: absolute;
        top: 0;
        left: 0;
        bottom: 0;
        right: 170px;
        overflow: auto;
      }
    }
  }
}
</style>